#	 Copyright 2012, 2012 Noel Warren

#    This file is part of MiniVistii.
#    MiniVistii is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Lesser General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    MiniVistii is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Lesser General Public License for more details.

#    You should have received a copy of the GNU Lesser General Public License
#    along with MiniVistii.  If not, see <http://www.gnu.org/licenses/>.

#The parser works it's way through the model finding entities that reprensent
#assemblies, workpieces, toolpaths and holes.  It then builds objects (concepts.rb)
#for the postprocessor to interpret more easily.

module Parser
    def self.parse()
		assemblies = []
		assemblies.push parseAssembly(Bundle.open(Sketchup::active_model))
		return assemblies
	end
	
	def self.parseToolpath(bundle, transformation)
		toolpath = Toolpath.new(bundle, transformation)
		return toolpath
	end
	
	def self.parseHole(bundle, transformation)
		hole = Hole.new(bundle, transformation)
		return hole
	end
	
	def self.parseStock(bundle, transformation)
		stock = Stock.new(bundle, transformation)
		return stock
	end
	
	def self.parseWorkpiece(bundle, transformation)
		workpiece = Workpiece.new(bundle, transformation)
		bundle.gather("stock").each{|bundleS, transformationS|
			workpiece.stock = parseStock(bundleS, transformationS)
		}
		bundle.gather("toolpath").each{|bundleT, transformationT|
			if bundleT.reprecussion?
				workpiece.reprecussionToolpaths.push [bundleT, transformationT]
			else
				workpiece.toolpaths.push parseToolpath(bundleT, transformationT)
			end
		} 
		bundle.gather("hole").each{|bundleH, transformationH|
			if bundleH.reprecussion?
				workpiece.reprecussionHoles.push [bundleH, transformationH]
			else
				workpiece.holes.push parseHole(bundleH, transformationH)
			end
		}
		return [workpiece, transformation]
	end
	
	def self.parseAssembly(bundle)
		gathering = bundle.gather("workpiece")
		gathering.collect!{|wpBundle, wpTransformation|
			parseWorkpiece(wpBundle, wpTransformation * Sketchup::active_model.edit_transform.inverse)
		}
		toolpathReprecussions = bundle.gather("toolpathreprecussion")
		holeReprecussions = bundle.gather("holereprecussion")
		gathering.each{|subjectWorkpiece, subjectTransformation|
			gathering.each{|objectWorkpiece, objectTransformation|
				if subjectWorkpiece.object_id != objectWorkpiece.object_id
					subjectWorkpiece.reprecussionToolpaths.each{|bundleT,transformationT|
						combinedTransformation = (subjectTransformation * transformationT)
						if objectWorkpiece.affected_by? bundleT, combinedTransformation
							objectWorkpiece.toolpaths.push parseToolpath(bundleT, (objectTransformation.inverse * combinedTransformation))
						end
					}
					subjectWorkpiece.reprecussionHoles.each{|bundleH,transformationH|
						combinedTransformation = (subjectTransformation * transformationH)
						if objectWorkpiece.affected_by? bundleH, combinedTransformation							
							objectWorkpiece.holes.push parseHole(bundleH, (combinedTransformation.inverse * objectTransformation))
							puts Toolbox.face(objectWorkpiece.holes.last.vector)
						end
					}
				end					
			}
		}
		assembly = Assembly.new(bundle)
		gathering.each{|workpiece, transformation|
			assembly.push workpiece
		}
		return assembly
	end
end
puts "Parser OK!"

